package com.szx.java.service.impl;

import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.szx.java.constants.WxConstants;
import com.szx.java.entity.Vo.WxTemplateVo;
import com.szx.java.entity.WToken;
import com.szx.java.mapper.WTokenMapper;
import com.szx.java.service.WTokenService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.szx.java.utils.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Date;
import java.util.Map;
import java.util.TreeMap;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author szx
 * @since 2023-05-30
 */
@Service
@Primary
public class WTokenServiceImpl extends ServiceImpl<WTokenMapper, WToken> implements WTokenService {
    @Autowired
    WeCharServiceImpl weCharService;

    /**
     * 获取Token
     * @return
     */
    public String getToken() {
        WToken token = this.getById(1);
        // 获取当前时间戳
        long nowTime = new Date().getTime();
        long tokenTime = TimeUtils.timeToTimestamp(token.getExpires());
        // 判断token是否过期
        if(nowTime >= tokenTime){
            // 重新请求token
            // 获取接口调用凭证
            String accessTokenStr = "https://api.weixin.qq.com/cgi-bin/token?" +
                    "grant_type=client_credential" + "&appid=" + WxConstants.WX_APPID + "&secret=" + WxConstants.WX_SECRET;
            String tokenStr = HttpUtil.get(accessTokenStr);
            JSONObject object = JSONUtil.parseObj(tokenStr);
            String accessToken = object.get("access_token").toString();
            // 更新token
            token.setToken(accessToken);
            // 更新过期时间
            token.setExpires(TimeUtils.now(7000));
            // 保存到数据库
            this.updateById(token);
            return accessToken;
        }else{
            // 返回数据库中保存的token
            return token.getToken();
        }
    }

    /**
     * 获取ticketToken
     * @return
     */
    public String getTickToken() {
        WToken tickToken = this.getById(2);
        // 获取当前时间戳
        long nowTime = new Date().getTime();
        long tokenTime = TimeUtils.timeToTimestamp(tickToken.getExpires());
        // 判断token是否过期
        if (nowTime >= tokenTime) {
            String token = getToken();
            String getTickUrl =
                    "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token="
                            + token
                            + "&type=jsapi";
            String jsonStr = HttpUtil.get(getTickUrl);
            JSONObject jsonObject = JSONUtil.parseObj(jsonStr);
            String ticket = jsonObject.get("ticket").toString();
            // 更新token
            tickToken.setToken(ticket);
            // 更新过期时间
            tickToken.setExpires(TimeUtils.now(7000));
            // 保存到数据库
            this.updateById(tickToken);
            return ticket;
        } else {
            // 返回数据库中保存的token
            return tickToken.getToken();
        }
    }

    /**
     * 微信接口配置，响应微信发送的Token验证
     */
    @Override
    public String checkToken(HttpServletRequest request, HttpServletResponse response) {
        if (StringUtils.isNotBlank(request.getParameter("signature"))) {
            String signature = request.getParameter("signature");
            String timestamp = request.getParameter("timestamp");
            String nonce = request.getParameter("nonce");
            String echostr = request.getParameter("echostr");
            if (SignUtil.checkSignature(signature, timestamp, nonce)) {
                return echostr;
            }
        }
        return "";
    }

    /**
     * 获取AccessToken
     * @return
     */
    @Override
    public String getAccessToken() {
        // 固定查询id等于1的数据
        WToken wToken = this.getById(1);
        // 判断当前的accessToken是否在有效期内,小于0表示在有效期内
        if(DateTimeUtils.CompareTime(wToken.getExpires()) < 0){
            return wToken.getToken();
        }else{
            // 不再有效期内时调用接口获取新的token
            String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&" +
                    "appid=" + WxConstants.WX_APPID +
                    "&secret=" + WxConstants.WX_SECRET;
            // 发送请求，获取json格式字符串
            String result_str = HttpUtil.get(url);
            // 将json格式的字符串转成JSONObject类型，方便获取里面的数据
            JSONObject result_json = JSONUtil.parseObj(result_str);
            // 从json中读取access_token字段，并转成string
            String access_token = result_json.get("access_token").toString();
            // 更新token
            wToken.setToken(access_token);
            // 更新过期时间
            wToken.setExpires(DateTimeUtils.FutureTime());
            // 更新数据库中的值
            this.updateById(wToken);
            // 返回最新的token
            return wToken.getToken();
        }
    }

    /**
     * 相应微信请求
     * @param request
     * @param response
     * @return
     */
    @Override
    public String postWeChar(HttpServletRequest request, HttpServletResponse response) {
        try {
            // 解析request中的xml得到一个map
            Map<String, String> xmlMap = XmlUtil.parseXml(request);
            // 判断是否事件类型
            String eventType = xmlMap.get("Event");
            // 判断map中是否存在Event，由此判断这个事件是普通消息还是事件推送
            if(StringUtils.isNotEmpty(eventType)){
                // 事件推送
                return weCharService.parseEvent(xmlMap);
            }else{
                // 普通消息
                return weCharService.parseMessage(xmlMap);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "";
    }

    /**
     * 发送模板消息
     */
    @Override
    public void sendTemplateMsg() {
        // 发送模板请求的地址
        String postUrl = "https://api.weixin.qq.com/cgi-bin/message/template/send" +
                "?access_token=" + getToken();
        // 要给那个用户发送模板消息
        String openId = "olttN6WJOYe-lTysV8_tsnZ7-HMQ";
        // 模板消息ID
        String templeID = "vRGjpYZ-uL3CCREW9c6Kl9csekoW9tVbVl7hf_y3k5U";
        // 点击模板消息要跳转的地址，如果不设置则不会跳转
        String templeUrl = "http://baidu.com";

        // 构造模板消息内容
        TreeMap<String, TreeMap<String, String>> params = new TreeMap<>();
        params.put("keyword1", WxTemplateVo.item("第一行消息", "#409EFF"));
        params.put("keyword2", WxTemplateVo.item("第二行消息", "#409EFF"));
        params.put("keyword3", WxTemplateVo.item("第三行消息", "#409EFF"));

        // 将模板消息放进实体类中
        WxTemplateVo wxTemplateMsg = new WxTemplateVo();
        wxTemplateMsg.setTemplate_id(templeID);
        wxTemplateMsg.setTouser(openId);
        wxTemplateMsg.setData(params);
        wxTemplateMsg.setUrl(templeUrl);

        // 请求请求
        HttpUtil.post(postUrl, JSONUtil.toJsonStr(wxTemplateMsg));
    }


}
